package CalculateWeights;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Collections;
import java.math.*;

import constants.Constants;

public class CalculateAttributeWeights {

	public Double calculateStreetAddressWeight(String address1, String address2)
	{
		
		
		
		return 0.0;
	}
	
	public Double calculateStateWeight(String state1, String state2)
	{
		
		
		
		return 0.0;
	}
	
	public Double calculateLocationAttribute(String locationAttribute1, String locationAttribute2)
	{
		Double locationAttributeWeight = new Double(0.0);
		
		if(!(locationAttribute1.equalsIgnoreCase("")) && !(locationAttribute2.equalsIgnoreCase("")) && !(locationAttribute1.equalsIgnoreCase(" ")) && !locationAttribute2.equalsIgnoreCase(" "))
		{
			if(locationAttribute1.equalsIgnoreCase(locationAttribute2))
			{
			locationAttributeWeight = 1.0;
			}
		}
		else if((!(locationAttribute1.equalsIgnoreCase("")) || !(locationAttribute2.equalsIgnoreCase(""))) && (!(locationAttribute1.equalsIgnoreCase(" ")) || !(locationAttribute2.equalsIgnoreCase(" "))))
		
		{
			locationAttributeWeight = 0.5;	
		}
		return locationAttributeWeight;
	}
	
	
	
	public int calculateCityWeight(String city1, String city2, String state, Connection conn)
	{
		
		ArrayList<Double> allPopulation = new ArrayList<Double>();
		Double maximumPopulation;
		Double minimumPopulation;
		Double cityPopulation = 0.0;
		int calculated_city_weight = 0;
		int indexOfPopulation = 0;
		
		if(city1.equalsIgnoreCase(city2))
		{
		String query1 = "select ps.pop_2009 from population_stats ps where ps.name <> ps.statename";
	//	String query2 = "select max(pop_2009) from population_stats ps where ps.name <> ps.statename";
	//	String query3 = "select min(pop_2009) from population_stats ps where ps.name <> ps.statename";
		String query4 = "select ps.pop_2009 from population_stats ps where ps.name <> ps.statename and name = ? and ps.statename =?";
		
		 try{
		
		//get average population of city	 
		 PreparedStatement st1 = conn.prepareStatement(query1);
		 ResultSet  rs1 = st1.executeQuery();
		 
		 while(rs1.next())
		 {
			 allPopulation.add(rs1.getDouble("ps.pop_2009"));
		 }
         
        //get maximum population of city 
//         PreparedStatement st2 = conn.prepareStatement(query2);
//		 ResultSet  rs2 = st2.executeQuery();
//         maximumPopulation = rs2.getDouble("max(pop_2009)");
//        
         //get minimum population of city  
//         PreparedStatement st3 = conn.prepareStatement(query3);
//		 ResultSet  rs3 = st3.executeQuery();
//         minimumPopulation = rs3.getDouble("min(pop_2009)"); 
//         
         //get city's population
         PreparedStatement st4 = conn.prepareStatement(query4);
         st4.setString(1, city1);
         st4.setString(2, state);
		 ResultSet  rs4 = st4.executeQuery();
		 while(rs4.next()){
         cityPopulation = rs4.getDouble("ps.pop_2009");
		 }
		 }
		 
		 catch(SQLException sqle)
		 {
			 sqle.printStackTrace();
		 }
		 
		 
		Collections.sort(allPopulation);
		 //assign weight depending on population of city
		 
		 for (int i=0; i<allPopulation.size(); i++)
		 {
			 
			 if(cityPopulation.equals(allPopulation.get(i))){
			 indexOfPopulation = i;
			 break;
		 }
		 }
		
		 //total count = 81703 - Approx 8000 records per set 
		
		if(cityPopulation != 0){ 
		 calculated_city_weight = calculated_city_weight + (80000/indexOfPopulation);
		}
		}	 
		return calculated_city_weight;
	}
	
	
	
	public Double comparePhoneAttributes(String phone1, String phone2)
	{
		
		System.out.println("Phone 1 is " + phone1);
		System.out.println("Phone 2 is " + phone2);
		
		
//		phone1.trim();
//		phone1.replaceAll("\\s+",""); 
//		phone1.replaceAll("\\(","");
//		phone1.replaceAll("\\-","");
//		phone1.replaceAll("\\)","");
//		phone2.trim();
//		phone2.replaceAll("[ ]","");
//		phone2.replaceAll("[(]","");
//		phone2.replaceAll("[-]","");
//		phone2.replaceAll("[)]","");
//		
		StringBuffer newPhone1 = new StringBuffer();
		
		for(int i=0;i<phone1.length();i++){
			if(containsOnlyNumbers(phone1.substring(i,i+1)))
			{
				newPhone1.append(phone1.charAt(i));
				//j++;
			}
		}
		
		StringBuffer newPhone2 = new StringBuffer();
		
		for(int i=0;i<phone2.length();i++){
			if(containsOnlyNumbers(phone2.substring(i,i+1)))
			{
				newPhone2.append(phone2.charAt(i));
			}
		}
		
		phone1 = newPhone1.toString();
		phone2 = newPhone2.toString();
		
		System.out.println("New Phone 1 is " + phone1);
		System.out.println("New Phone 2 is " + phone2);
		Double calculated_phone_weight = new Double(-1.0);
		
		
		
		if ((phone1.length() == 10 && phone2.length() == 10))	
		{
			
			//if all 10 digits are same 
			if(phone1.equals(phone2))
				{
				   calculated_phone_weight = Constants.FF_PHONE__WEIGHT;
			   }
			 } 
			 
		//This checks, if both phone numbers are partial
		else if(phone1.length() <10 && phone2.length() <10 && !(phone1.length() <= 1) && !(phone2.length() <=1))
		{
			if(phone1.equals(phone2)){
			calculated_phone_weight = Constants.PP_PHONE__WEIGHT;
			}
		}	
			
		//This checks, if one of the phones has 10 digits
		else if ((phone1.length() == 10 || phone2.length() == 10) && !(phone1.length() <= 1) && !(phone2.length() <=1))
		{
			
		   if(phone1.length() ==10)
		   {
			 //first phone contains all 10 digits
			  String partPhone1 = phone1.substring(0,phone2.length());
			  System.out.println("Part phone 1 is " + partPhone1);
			  if(partPhone1.equals(phone2))
			  {
				  calculated_phone_weight = Constants.FP_PHONE__WEIGHT;  
			  }
		   }
		   else  if(phone2.length() ==10)
		   {
			 //first phone contains all 10 digits
			  String partPhone2 = phone2.substring(0,phone1.length());
			  System.out.println("Part phone 2 is " + partPhone2);
			  if(partPhone2.equals(phone1))
			  {
				  calculated_phone_weight = Constants.FP_PHONE__WEIGHT;  
			  }
		   }
		}  
		   else if (phone1.length() <=1 && phone2.length() <=1)
		   {
			   calculated_phone_weight = Constants.NN_PHONE__WEIGHT;   
		   }
		   
		   else if (phone1.length() <= 1 || phone2.length() <=1)
		   {
			   calculated_phone_weight = Constants.FN_PN_PHONE__WEIGHT;
		   }
			
			
		return calculated_phone_weight;
	}
	
	
	public Double compareAgeAttributes(String age1, String age2)
	{
		Double calculatedAgeWeight = new Double(-1.0);
		
	if(!(age1.equals(" ")) && !(age2.equals(" ")) && !(age1.equals("")) && !(age2.equals("")))	
	{	
		
       StringBuffer newAge1 = new StringBuffer();
		
		for(int i=0;i<age1.length();i++){
			if(containsOnlyNumbers(age1.substring(i,i+1)))
			{
				newAge1.append(age1.charAt(i));
				//j++;
			}
		}
		
		StringBuffer newAge2 = new StringBuffer();
		
		for(int i=0;i<age2.length();i++){
			if(containsOnlyNumbers(age2.substring(i,i+1)))
			{
				newAge2.append(age2.charAt(i));
			}
		}
		
		age1 = newAge1.toString();
		age2 = newAge2.toString();
		
	//	System.out.println("New Age 1 is " + age1);
	//	System.out.println("New Age 2 is " + age2);
		
		
		
		
		Integer valueAge1 = Integer.parseInt(age1);
		Integer valueAge2 = Integer.parseInt(age2);
		
		Integer differenceAge = Math.abs(valueAge1 - valueAge2);
		if(differenceAge <= 3)
		{
			calculatedAgeWeight = 1.0;	
		}
	}
	
	else if(!(age1.equals(" ")) || !(age2.equals(" ")) || !(age1.equals(" ")) || !(age2.equals(" ")))
			{
		calculatedAgeWeight = 0.0;
			}
		return calculatedAgeWeight;
	}
	
	
	
	
	public Double compareNameAttributes(String name1, String name2)
	{
		Double calculated_name_weight = new Double(-1.0);
		
		//remove extra comma from both names
		name1.replaceAll(",", "");
		name2.replaceAll(",", "");
		
		name1.trim();
		name2.trim();
		
		
		//name1.replaceAll("^\\s+", "");
		//name2.replaceAll("^\\s+", "");
		
		
		
		if(name1.startsWith(" "))
		{
			name1.replaceFirst("\\s+", "");
			//name1.
		}
		
		if(name2.startsWith(" "))
		{
			name2.replaceFirst("\\s+", "");
		}
				
		
		
		//remove double and triple spaces
//		name1.replaceAll("   ", " ");
//		name2.replaceAll("   ", " ");
//		System.out.println("Name 1 is " + name1);
//		System.out.println("Name 2 is " + name2);
//		
//		
//		name1.replaceAll("  ", " ");
//		name2.replaceAll("  ", " ");
//		
		
		System.out.println("Name 1 is " + name1);
		System.out.println("Name 2 is " + name2);
		
	//if(name1.contains("\\s+") && name2.contains("\\s+")){	
		String[] nameSplit1 = name1.split("\\s+");
		String[] nameSplit2 = name2.split("\\s+");
		
		System.out.println("Name Split 1 is " + nameSplit1[0] + ";" + nameSplit1[1]);
		System.out.println("Name Split 2 is " + nameSplit2[0] + ";" + nameSplit2[1]);
		
		String firstName1;
		String firstName2;
		String lastName1;
		String lastName2;
		String middleName1;
		String middleName2;
		
		if ((nameSplit1.length == 3 && nameSplit2.length == 3)  && (nameSplit1.length >1 && nameSplit2.length >1))	
		{
			
			//first name contains middle name
			   firstName1 = nameSplit1[0];
			   middleName1 = nameSplit1[1];	
			   lastName1 = nameSplit1[2];
			
			
			 //second name contains middle name
			   firstName2 = nameSplit2[0];
			   middleName2 = nameSplit2[1];	
			   lastName2 = nameSplit2[2];
			
		//if all 3 are same This case takes checks, whether name has full middle names
			 if(middleName1.length() > 1 && middleName2.length() > 1)
			 {  if(firstName1.equalsIgnoreCase(firstName2) && lastName1.equalsIgnoreCase(lastName2) && middleName1.equalsIgnoreCase(middleName2))	   
			   {
				   calculated_name_weight = Constants.FMFM_NAME_WEIGHT;
			   }
			 } 
			 
		//else check for similarity of a middle name initials	 
			 else if(middleName1.length() == 1 && middleName2.length() == 1)
			 {
				 if(firstName1.equalsIgnoreCase(firstName2) && lastName1.equalsIgnoreCase(lastName2) && middleName1.equalsIgnoreCase(middleName2))	   
				   {
					   calculated_name_weight = Constants.IMIM_NAME_WEIGHT;
				   } 
			 }
		//check for similarity of a middle name initial with full middle name	   
			   else if(firstName1.equalsIgnoreCase(firstName2) && lastName1.equalsIgnoreCase(lastName2))
				   
			   {
				   //check the middle name initials
				 if(middleName1.length() == 1)
				 {
					 String middleName2Initial = middleName2.substring(0, 0);
					 System.out.println("middleName2Initial = " + middleName2Initial);
					 
					 if(middleName1.equalsIgnoreCase(middleName2Initial))
					 {
						 calculated_name_weight = Constants.FMIM_NAME_WEIGHT;	 
					 }
				 }
						 
				 else if( middleName2.length() == 1)
				 {
					 String middleName1Initial = middleName1.substring(0, 0);
					 System.out.println("middleName1Initial = " + middleName1Initial);
					 
					 if(middleName2.equalsIgnoreCase(middleName1Initial))
					 {
						 calculated_name_weight = Constants.FMIM_NAME_WEIGHT;	 
					 }
				 }
				   
				 
			   }
			   
			}
		
		
		
		//This checks, if both names contain just first and last names and no middle names
		else if(nameSplit1.length ==2 && nameSplit2.length ==2)
		{
			firstName1 = nameSplit1[0];
			lastName1 = nameSplit1[1];
			firstName2 = nameSplit2[0];
			lastName2 = nameSplit2[1];
			
			if(firstName1.equalsIgnoreCase(firstName2) && lastName1.equalsIgnoreCase(lastName2))
			{
				calculated_name_weight = Constants.FIRST_LAST_NAME_WEIGHT;
				System.out.println("Only F and l are similar");
				
			}
		}	
			
		//This checks, if one of the names contain middle name
		else if ((nameSplit1.length == 3 || nameSplit2.length == 3) && (nameSplit1.length >1 && nameSplit2.length >1))
		{
		   if(nameSplit1.length ==3)
		   {
			 //first name contains middle name as well
			   firstName1 = nameSplit1[0];
			   middleName1 = nameSplit1[1];	
			   lastName1 = nameSplit1[2];
			 
			 //second name contains only first and last names
				firstName2 = nameSplit2[0];
				lastName2 = nameSplit2[1];
				//calculateMiddleNameWeight(mid)
		   }
		   else // if(nameSplit2.length ==3)
		   {
			   
			   //first name contains only first and last names
			   firstName1 = nameSplit1[0];
			   lastName1 = nameSplit1[1];
			   
			   
			   //second name contains middle name as well
			   firstName2 = nameSplit2[0];
			   middleName2 = nameSplit2[1];	
			   lastName2 = nameSplit2[2];
		   }
			
		   if(firstName1.equalsIgnoreCase(firstName2) && lastName1.equalsIgnoreCase(lastName2))
			{
			   calculated_name_weight = Constants.FMNM_IMNM_NAME_WEIGHT;
			}
			
	//	}

	}	
		return calculated_name_weight;
	}
	
	
	public Double calculateLocationWeight(Double stateWeight, Double cityWeight, Double streetWeight, Double zipWeight)
	{
		Double locationWeight = new Double(-1.0);
		
		if(((stateWeight.equals(new Double(1.0))) && (cityWeight.equals(new Double(1.0))) && (streetWeight.equals(new Double(1.0))) && (zipWeight.equals(new Double(1.0))))
		|| ((stateWeight.equals(new Double(1.0))) && (cityWeight.equals(new Double(1.0))) && (streetWeight.equals(new Double(1.0))) && (zipWeight >= 0.5))
		|| ((stateWeight.equals(new Double(1.0))) && (cityWeight>=0.5) && (streetWeight.equals(new Double(1.0))) && (zipWeight.equals(new Double(1.0))))
		|| ((stateWeight.equals(new Double(0.5))) && (cityWeight.equals(new Double(1.0))) && (streetWeight.equals(new Double(1.0))) && (zipWeight.equals(new Double(1.0)))))
		{
			locationWeight = 1.0;
		}
		
		else if(((stateWeight.equals(new Double(1.0))) && (cityWeight.equals(new Double(1.0))) && (streetWeight.equals(new Double(0.5))) && (zipWeight.equals(new Double(0.0))))
				|| ((stateWeight.equals(new Double(1.0))) && (cityWeight.equals(new Double(0.0))) && (streetWeight.equals(new Double(0.5))) && (zipWeight.equals(new Double(1.0)))))
				{
			locationWeight = 0.5;
				}
		
		else if(((stateWeight.equals(new Double(0.5))) && (cityWeight.equals(new Double(1.0))) && (streetWeight.equals(new Double(1.0))) && (zipWeight.equals(new Double(0.5))))
				|| ((stateWeight.equals(new Double(0.5))) && (cityWeight.equals(new Double(0.5))) && (streetWeight.equals(new Double(1.0))) && (zipWeight.equals(new Double(1.0)))))
				{
			locationWeight = 0.25;
				}
		
		else if(((stateWeight.equals(new Double(1.0))) && (cityWeight >= 0.5) && (streetWeight.equals(new Double(0.0))) && (zipWeight.equals(new Double(0.0))))
				|| ((stateWeight.equals(new Double(1.0))) && (cityWeight.equals(new Double(0.0))) && (streetWeight.equals(new Double(0.0))) && (zipWeight>=0.5)))
				{
			locationWeight = 0.0;
				}
		
		else if(((stateWeight.equals(new Double(0.5))) && (cityWeight.equals(new Double(0.5))) && (streetWeight.equals(new Double(0.5))) && (zipWeight.equals(new Double(1.0))))
				|| ((stateWeight.equals(new Double(0.5))) && (cityWeight.equals(new Double(1.0))) && (streetWeight.equals(new Double(0.5))) && (zipWeight.equals(new Double(0.5)))))
				{
			locationWeight = -0.25;
				}
		
		else if(((stateWeight.equals(new Double(0.5))) && (cityWeight.equals(new Double(0.0))) && (streetWeight.equals(new Double(0.0))) && (zipWeight.equals(new Double(0.0)))))
				{
			locationWeight = -0.5;
				}
		
		else if(((stateWeight.equals(new Double(0.0)))) 
				|| ((stateWeight.equals(new Double(1.0))) && (cityWeight.equals(new Double(0.0))) && (streetWeight.equals(new Double(0.0))) && (zipWeight.equals(new Double(0.0))))
				|| ((stateWeight.equals(new Double(0.0))) && (cityWeight.equals(new Double(1.0))) && (streetWeight.equals(new Double(0.0))) && (zipWeight.equals(new Double(0.0)))))
				{
					locationWeight = -1.0;
				}
		
		
		return locationWeight;
	}
	
	 public static boolean containsOnlyNumbers(String str) {
		   
		   boolean isNumber = true;
		   try
		   
		   {
		   
		   /*
		   #
		   * To check if the number is valid integer number, use
		   #
		   * int parseInt(String str) method of
		   #
		   * Integer wrapper class.
		   #
		   *
		   #
		   * This method throws NumberFormatException if the
		   #
		   * argument string is not a valid integer number.
		   #
		   */
	       Integer.parseInt(str);
		   
		  // System.out.println(str + " is valid integer number");
		   
		   }
		   
		   catch(NumberFormatException nme)
		   {
		   isNumber = false;
		  // System.out.println(str + " is not a valid integer number");
		  }
		   
		   return isNumber;
		   
	}
	
	
}
